﻿// SendForm.cpp : Implementation of CSendForm

#include "stdafx.h"
//#include <Windows.h>
//#include <WindowsX.h>
#include <vector>
#include "SendForm.h"
#include "ServiceProvider.h"
#include "../omsproxy/OMSClientConcrete.h"
#include "ContactsForm.h"
#include "Helper.h"
using namespace std;

// CSendForm

void CSendForm::splitEx(const std::wstring& src, const std::wstring& separate_character, vector<wstring*>* outputlist)
{
	if(!outputlist) outputlist = new vector<wstring*>();
	int separate_characterLen = separate_character.size();
    int lastPosition = 0,index = -1;

	wstring* item;
    while (-1 != (index = src.find(separate_character,lastPosition)))
    {
		item = new wstring(src.substr(lastPosition,index - lastPosition));
		outputlist->push_back(item);
        lastPosition = index + separate_characterLen;
    }
    item = new wstring(src.substr(lastPosition));
    if (!item->empty())
        outputlist->push_back(item);
}

void CSendForm::LoadNativeForm()
{
	//find service provider
	if(!regesiter)
		regesiter = new Regesiter();
	if(!serviceProviders)
		serviceProviders = new std::vector<ServiceProvider*>();
	if(regesiter->LoadServiceProvider(serviceProviders) < 0) return;
	//if found
		//send provider list to combo
		//enabled send button

	if(serviceProviders->size() > 0){
		//
		HWND hSendButton = ::GetDlgItem(m_hWnd,IDC_BUTTON_SEND);
		::EnableWindow(hSendButton,TRUE);
		//
		HWND hCmbPros = ::GetDlgItem(m_hWnd, IDC_COMBO_PROS);
		for(vector<ServiceProvider*>::iterator iter = serviceProviders->begin();
			iter != serviceProviders->end();
			iter++)
		{
			//(*iter)->ServiceProviderName
			::SendMessageW(hCmbPros,CB_ADDSTRING,NULL,(LPARAM)((*iter)->ServiceProviderName.c_str()));
		}
		//select first
		::SendMessageW(hCmbPros,CB_SETCURSEL,(WPARAM)0,NULL);
		//manual invoke event
		BOOL t;
		OnCbnSelchangeComboPros(0,0,NULL,t);
	}
	//else not found
	//disabled send button , give message
	else{
		HWND hSendButton = ::GetDlgItem(m_hWnd,IDC_BUTTON_SEND);
		::EnableWindow(hSendButton,FALSE);
		::MessageBoxW(0,L"No avaliable provider is found!",L"Missing provider",MB_ICONWARNING);
	}
}

ServiceProvider* CSendForm::GetCurServiceProvider()
{
	HWND hWndCtl = ::GetDlgItem(m_hWnd,IDC_COMBO_PROS);
	int nlength = ::GetWindowTextLengthW(hWndCtl);
	wchar_t* szText = new wchar_t[nlength+1];
	::GetWindowTextW(hWndCtl,szText,nlength+1);
	for(vector<ServiceProvider*>::iterator iter = serviceProviders->begin();
		iter != serviceProviders->end();
		iter++)
	{
		if(wcscmp((*iter)->ServiceProviderName.c_str(),szText) == 0){
			delete []szText;
			return *iter;
		}
	}
	delete []szText;
	return NULL;
}

LRESULT CSendForm::BuildXmsDataInternal(
	std::wstring& userName , 
	std::wstring& Password , 
	std::wstring& ReplyPhone , 
	std::wstring& Content , 
	std::vector<std::wstring*>* receiverlist ,
	std::wstring& result)
{
	LPCWSTR xmsDataPattern = 
		L"<?xml version=\"1.0\" encoding=\"utf-16\" standalone=\"yes\"?>\
		 <xmsData client=\"Microsoft Office Outlook 12.0\" xmlns = \"http://schemas.microsoft.com/office/Outlook/2006/OMS\"> \
				<user>\
					<userId>%s</userId>\
					<password>%s</password>\
					<replyPhone>%s</replyPhone>\
					<customData/>\
				</user>\
				<xmsHead>\
					<requiredService>SMS_SENDER</requiredService>\
					<sourceType>other</sourceType>\
					<to>%s</to>\
				</xmsHead>\
				<xmsBody format=\"SMS\">\
					<content contentType=\"text/plain\" contentId=\"\" contentLocation=\"\">%s</content>\
				</xmsBody>\
			</xmsData>";

	LPCWSTR recipientitemPattern = L"<recipient>%s</recipient>";
	wchar_t* buffer;
	std::wstring receivers;
	for(std::vector<std::wstring*>::iterator iter = receiverlist->begin();
		iter != receiverlist->end();
		iter++)
	{
		long len = (*iter)->length();
		if(len == 0) continue;
		buffer = new wchar_t[len+24];
		wsprintfW(buffer,recipientitemPattern,EscapXml(**iter).c_str());
		receivers.append(buffer);
		delete[] buffer;
	}
	buffer = new wchar_t[Content.length() + receivers.length() + 600];
	wsprintfW(buffer,xmsDataPattern,
		EscapXml(userName).c_str(),
		EscapXml(Password).c_str(),
		EscapXml(ReplyPhone).c_str(),
		receivers.c_str(),
		EscapXml(Content).c_str());
	result = buffer;
	return 0;
}


LRESULT CSendForm::OnBnClickedButtonSend(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
	Outlook::MAPIFolderPtr sentBox = m_app->GetNamespace(L"MAPI")->GetDefaultFolder(Outlook::olFolderSentMail);
	Outlook::_PostItemPtr newItem = m_app->CreateItem(Outlook::olPostItem);
	std::wstring response;
	std::wstring szContent;
	std::wstring xmsDataTobeSend; //result
	//get receivers list
	vector<wstring*>* receiverlist = new vector<wstring*>();//!!!!!!!
	HWND hEdit = NULL;
	hEdit = ::GetDlgItem(m_hWnd, IDC_EDIT_RECEIVERS);
	ATLASSERT(hEdit);
	
	int nLength = ::GetWindowTextLengthW(hEdit);
	wchar_t* input = new wchar_t[nLength+1];
	::GetWindowTextW(hEdit,input,nLength+1);
	//::SendMessageW(hEdit,WM_GETTEXT,1024,(LPARAM)input);
	wstring receivers(input);
	delete[] input;
	if(receivers.empty()){
		::MessageBoxW(0,L"Please input mobile numbers",L"Tips",MB_ICONWARNING);
		return 0;
	}
	receivers.append(L";");
	wstring::size_type pos = 0;
	splitEx(receivers,L";",receiverlist);	//push receiver in the list
	
	//for(vector<wstring*>::iterator i = receiverlist->begin();
	//	i!=receiverlist->end();
	//	i++)
	//{
	//	if((*i)->empty()) continue;
	//	MessageBoxW((*i)->c_str(),L"1",MB_OK);
	//}
	ServiceProvider* CurProvider = GetCurServiceProvider();
	if(CurProvider == NULL){
		::MessageBoxW(0,L"Please configure service provider and select one!",L"Tips",MB_ICONWARNING);
		goto err_realse;
	}	
	//get content
	HWND hEditContent = ::GetDlgItem(m_hWnd,IDC_EDIT_CONTENT);
	nLength = ::GetWindowTextLengthW(hEditContent);
	if(nLength == 0){
		::MessageBoxW(0,L"Content is Empty!",L"Tips",MB_ICONWARNING);
		goto err_realse;
	}
	szContent.resize(nLength+1);
	::GetWindowTextW(hEditContent,(LPWSTR)szContent.data(),nLength+1);

	EndDialog(wID);

	/*build xmsData*/

	if(BuildXmsDataInternal(CurProvider->UserName,
		CurProvider->UserPwd,
		CurProvider->ReplyPhone,
		szContent,
		receiverlist,
		xmsDataTobeSend) != 0) goto err_realse;

	//MessageBoxW(xmsDataTobeSend.c_str(),L"",0);

	// push in the sentbox

	newItem->Subject = receivers.c_str();
	newItem->Body = szContent.c_str();
	try{
		IDispatchPtr movedItem = newItem->Move(sentBox);
	}
	catch(...){}


	/*invoke service*/
	if(m_client == NULL)
		m_client = (OMSClientBase*)new OMSClientConcrete();
	m_client->SendSMS(CurProvider->ServiceUri,xmsDataTobeSend,response);
	
err_realse:
	if(receiverlist){
		for(vector<wstring*>::iterator i = receiverlist->begin();
			i!=receiverlist->end();
			i++){
			delete (*i);
		}
		delete receiverlist;
	}
	//notify if failed
	if(!response.empty())
		NotifySendFailedInfo(response);
	return 0;
}


LRESULT CSendForm::OnCbnSelchangeComboPros(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	wstring content;
	content.append(L"URL:");
	ServiceProvider* CurProvider = GetCurServiceProvider();
	content.append(CurProvider->ServiceUri);
	HWND hEditProvider = ::GetDlgItem(m_hWnd,IDC_EDIT_PROVIDER);
	::SetWindowTextW(hEditProvider,content.c_str());
	return 0;
}


//TODO : May need parse the failed mobile and list them for user
void CSendForm::NotifySendFailedInfo(const std::wstring& response)
{
	std::wstring errorCode;
	std::wstring mailContent;
	std::wstring UnreachedReceiver;
	std::wstring UnreachedContent;
	//if failed report the return response
	if(parser->FindSendResponseErrorCode(response,errorCode) != 0
		|| wcscmp(errorCode.c_str(),L"ok") != 0){
		mailContent = response;
		goto report;
	}
	return;
report:
	Outlook::MAPIFolderPtr sentBox = m_app->GetNamespace(L"MAPI")->GetDefaultFolder(Outlook::olFolderInbox);
	Outlook::_PostItemPtr newItem = m_app->CreateItem(Outlook::olPostItem);
	newItem->Subject = _bstr_t(L"SMS Send Failed(system post back)");
	if(parser->FindSendResponseUnreachedReceiver(response,UnreachedReceiver) == 0){
		mailContent.append(L"\nUnreached receivers below:\n");
		mailContent.append(UnreachedReceiver);
	}
	if(parser->FindSendResponseUnreachedContent(response,UnreachedContent) == 0){
		mailContent.append(L"\nUnreached content below:\n");
		mailContent.append(UnreachedContent);
	}
	newItem->Body = mailContent.c_str();
	newItem->UnRead = true;
	newItem->Save();
}


LRESULT CSendForm::OnBnClickedButtonReceivers(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	//outlook application point
	ATLASSERT(m_app);
	if(!contactForm)
		contactForm = new CContactsForm(m_app);
	contactForm->DoModal();
	std::wstring append;
	contactForm->GetAppendContactList(append);
	std::wstring orignal;
	HWND hEditContacts = ::GetDlgItem(m_hWnd,IDC_EDIT_RECEIVERS);
	int szOrignalLength = ::GetWindowTextLengthW(hEditContacts);
	if(szOrignalLength != 0){
		WCHAR* szText = new WCHAR[szOrignalLength+1];
		::GetWindowTextW(hEditContacts,szText,szOrignalLength+1);
		orignal = szText;
		delete[] szText;	
		if(orignal.substr(orignal.length()-1,1) != L";") orignal.append(L";");
	}

	orignal.append(append);

	::SetWindowTextW(hEditContacts,orignal.c_str());
	return 0;
}
